﻿/***********************************************************************************************
 * 
 * ProjectName: WMSSoft.Lib.WinKStart
 * 
 * Description: FavoritenRader Class contains an startmenuitem reading from disk
 * 
 * Created:     27.12.2013
 * 
 * Author:      matthias wagler - matthias@WMSSoft.de
 * 
 * Copyright:   Copyright 2012 by WMSSoft.de
 * 
 * License:     GPLv3
 * 
 * History:     27.12.2013 - matthias wagler matthias@WMSSoft.de   -   Created
 * 
 **********************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using WMSSoft.Lib.Enums;
using WMSSoft.Lib.WinKStart;

namespace WMSSoft.WinKStart.DataSource.FavoriteReader
{
    /// <summary>
    /// Class to read/write Favoriten-Item from/to disk
    /// </summary>
    public class cFavoritenReader
    {
        private cStartmenuItem _RootFavoritenItem = null;
        private cStartmenuItem _FavoritenParent = null;
        private cStartmenuItem _FavoriteDocumentsParent = null;
        private System.IO.FileSystemWatcher m_FileSystemWatcher = null;
        private string _FavoriteConfigPath = "";
        private const string _FavoriteConfigFile = "Favconf.xml";
        private const string _FavoritenXMLParentNode = "FavoritenConfig";
        private const string _FavoritenXMLParentNamespace = "Faviconf.xsd";
        private const string _FavoritesXMLElement = "Favorites";
        private const string _FavoriteDocumentsXMLElement = "FavoriteDocuments";
        private const string _FavoriteXMLElement = "Favorite";
        private const string _FavoriteDocumentXMLElement = "FavoriteDocuments";
        private const string _FavoriteXMLElementFileAttributeName = "File";
        const string _FavoriteXMLElementAttributeName_Arguments = "Arguments";
        const string _FavoriteXMLElementAttributeName_DisplayName = "DisplayName";
        private const string _FavoriteXMLElementClicksAttributeName = "Usage";
        private DispatcherTimer m_DataLoadState = null;

        public event EventHandler LoadCompleted;

        public cFavoritenReader()
        {
            try
            {
                
                _RootFavoritenItem = new cStartmenuItem("FAVORITENROOT", "Favoriten", eLinkExecutionTypes.Program, "", eExecutionProcedure.Unknown,
                                                    eItemType.Root, "", null, null, "", "", "", "");
                _FavoritenParent = new cStartmenuItem("Favorites", "Favorite Programs", eLinkExecutionTypes.Unknown, "", eExecutionProcedure.Unknown, 
                                                                    eItemType.Label, "", null, _RootFavoritenItem, "", "", "", 0, "Tahoma", 10,
                                                                    System.Windows.Media.Color.FromRgb(128,128,128),20, eXMLHorizontalAlign.Right, 
                                                                    eXMLVerticalAlign.Center,"","");
                _FavoriteDocumentsParent = new cStartmenuItem("FavoriteDocuments", "Favorite Documents", eLinkExecutionTypes.Unknown, "", eExecutionProcedure.Unknown,
                                                                    eItemType.Label, "", null, _RootFavoritenItem, "", "", "", 0, "Tahoma", 10,
                                                                    System.Windows.Media.Color.FromRgb(128, 128, 128), 20, eXMLHorizontalAlign.Right,
                                                                    eXMLVerticalAlign.Center, "", "");
                _FavoritenParent.ContentType = eContentPanelContentType.Favorites;
                _RootFavoritenItem.AddChild(_FavoritenParent);

                _FavoriteDocumentsParent.ContentType = eContentPanelContentType.FavoriteDocuments;
                _RootFavoritenItem.AddChild(_FavoriteDocumentsParent);
                //Get path to load/save favoriten config
                _FavoriteConfigPath = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"WMSSoft\WinKStart\Conf");
                
                if (System.IO.Directory.Exists(_FavoriteConfigPath) == false)
                    System.IO.Directory.CreateDirectory(_FavoriteConfigPath);

                m_DataLoadState = new DispatcherTimer(DispatcherPriority.Normal);
                m_DataLoadState.Interval = new TimeSpan(0, 0, 1);
                m_DataLoadState.Tick += m_DataLoadState_Tick;
                //load favoriten from disk
                m_FileSystemWatcher = new System.IO.FileSystemWatcher(_FavoriteConfigPath, _FavoriteConfigFile);       
                m_FileSystemWatcher.EnableRaisingEvents = true;
                m_FileSystemWatcher.Created += m_FileSystemWatcher_Activate;
                m_FileSystemWatcher.Changed += m_FileSystemWatcher_Activate;
                m_FileSystemWatcher.Deleted += m_FileSystemWatcher_Activate;
                //LoadFromDisk();
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_WHILE_LOADING_FAVORITE_ITEMS, ex);
            }
        }

        void m_DataLoadState_Tick(object sender, EventArgs e)
        {
            m_DataLoadState.Stop();
            LoadFromDisk();
            if (LoadCompleted != null) LoadCompleted(this, EventArgs.Empty);
        }

        void m_FileSystemWatcher_Activate(object sender, System.IO.FileSystemEventArgs e)
        {
            m_DataLoadState.Start();
            //LoadFromDisk();
        }

        #region Properties
        /// <summary>
        /// Gives the Item that contains the Favoriten - Items
        /// </summary>
        public cStartmenuItem FavoritenRoot
        {
            get { return _RootFavoritenItem; }
        }
        #endregion

        /// <summary>
        /// Add a File (Program) to Favorites
        /// </summary>
        /// <param name="File">Link - Filename to add to program favorites list</param>
        public void AddFavorite(string File)
        {
            try
            {
                if (System.IO.File.Exists(File) == true)
                {
                    cStartmenuItem newFavoriteItem = cStartmenuItem.MakeInstance(File, _FavoritenParent);
                    if (newFavoriteItem != null  )
                    {
                        newFavoriteItem.ContentType = eContentPanelContentType.Favorites;
                        _FavoritenParent.AddChild(newFavoriteItem);
                        SaveToDisk();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_ADDING_FAVORITE_PROGRAM, ex);
            }
        }

        /// <summary>
        /// Add a File (Document) to Favorites
        /// </summary>
        /// <param name="File">Link - Filename to add to documents favorites list</param>
        public void AddFavoriteDocument(string File)
        {
            try
            {
                if (System.IO.File.Exists(File) == true)
                {
                    cStartmenuItem newFavoriteItem = cStartmenuItem.MakeInstance(File, _FavoritenParent);
                    if (newFavoriteItem != null)
                    {
                        newFavoriteItem.ContentType = eContentPanelContentType.FavoriteDocuments;
                        _FavoriteDocumentsParent.AddChild(newFavoriteItem);
                        SaveToDisk();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_ADDING_FAVORITE_DOCUMENT, ex);
            }
        }

        /// <summary>
        /// remove a favorite from programs and documents favorite list
        /// </summary>
        /// <param name="File"></param>
        public void RemoveFavorite(string File)
        {
            try
            {
                if (_FavoritenParent.ChildItems.ContainsKey(File.ToUpper()) == true)
                    _FavoritenParent.RemoveChild(File);
                else if (_FavoriteDocumentsParent.ChildItems.ContainsKey(File.ToUpper()) == true)
                    _FavoriteDocumentsParent.RemoveChild(File);
                //persistent favorite list to disk
                SaveToDisk();
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_REMOVING_FAVORITE, ex);
            }
        }

        /// <summary>
        /// Saves Favorites to File on Disk
        /// </summary>
        public void SaveToDisk()
        {
            try
            {
                //save favoriten to disk
                System.Xml.XmlDocument FavoritenDocument = new System.Xml.XmlDocument();
                FavoritenDocument.AppendChild(FavoritenDocument.CreateXmlDeclaration("1.0", "utf-8", String.Empty));
                System.Xml.XmlElement RootElement = FavoritenDocument.CreateElement(_FavoritenXMLParentNode, _FavoritenXMLParentNamespace);
                System.Xml.XmlElement ChildElements = null;
                System.Xml.XmlElement ChildElement = null;
                FavoritenDocument.AppendChild(RootElement);
                cStartmenuItem CurrentItem = null;

                ChildElements = FavoritenDocument.CreateElement(_FavoritesXMLElement);
                RootElement.AppendChild(ChildElements);

                Dictionary<string, object>.KeyCollection FavoritenParentKeys = _FavoritenParent.ChildItems.Keys;

                foreach (string Item in FavoritenParentKeys) 
                //for (int iChildCounter = 0; iChildCounter < _FavoritenParent.LinkItemList.Count; iChildCounter++)
                {
                    ChildElement = null;
                    CurrentItem = null;
                    //CurrentItem = ((cStartmenuItem)_FavoritenParent.ChildItems[_FavoritenParent.LinkDisplayNames[_FavoritenParent.LinkItemList[iChildCounter]]]);
                    CurrentItem = ((cStartmenuItem)_FavoritenParent.ChildItems[Item]);

                    if (CurrentItem != null && CurrentItem.ItemType != eItemType.Label)
                    {
                        
                        ChildElement = FavoritenDocument.CreateElement(_FavoriteXMLElement);
                        ChildElement.Attributes.Append(FavoritenDocument.CreateAttribute(_FavoriteXMLElementFileAttributeName));
                        ChildElement.Attributes.Append(FavoritenDocument.CreateAttribute(_FavoriteXMLElementClicksAttributeName));

                        ChildElement.Attributes[_FavoriteXMLElementFileAttributeName].InnerText = CurrentItem.ItemName;
                        ChildElement.Attributes[_FavoriteXMLElementClicksAttributeName].InnerText = "0";
                        
                        ChildElements.AppendChild(ChildElement);
                    }
                }

                ChildElements = FavoritenDocument.CreateElement(_FavoriteDocumentsXMLElement);
                RootElement.AppendChild(ChildElements);

                Dictionary<string, object>.KeyCollection FavoriteDocumentParentKeys = _FavoriteDocumentsParent.ChildItems.Keys;

                foreach (string Item in FavoriteDocumentParentKeys)
                //for (int iChildCounter = 0; iChildCounter < _FavoriteDocumentsParent.ChildItems.Count; iChildCounter++)
                {
                    ChildElement = null;
                    CurrentItem = null;
                    //CurrentItem = ((cStartmenuItem)_FavoriteDocumentsParent.ChildItems[_FavoriteDocumentsParent.LinkDisplayNames[_FavoriteDocumentsParent.LinkItemList[iChildCounter]]]);                    
                    CurrentItem = ((cStartmenuItem)_FavoriteDocumentsParent.ChildItems[Item]);

                    if (CurrentItem != null && CurrentItem.ItemType != eItemType.Label)
                    {
                        
                        ChildElement = FavoritenDocument.CreateElement(_FavoriteDocumentXMLElement);
                        ChildElement.Attributes.Append(FavoritenDocument.CreateAttribute(_FavoriteXMLElementFileAttributeName));
                        ChildElement.Attributes.Append(FavoritenDocument.CreateAttribute(_FavoriteXMLElementClicksAttributeName));

                        ChildElement.Attributes[_FavoriteXMLElementFileAttributeName].InnerText = CurrentItem.ItemName;
                        ChildElement.Attributes[_FavoriteXMLElementClicksAttributeName].InnerText = "0";
                        
                        ChildElements.AppendChild(ChildElement);
                    }
                }

                    //Save Favoriten - Configuration to file                
                    if (System.IO.Directory.Exists(_FavoriteConfigPath) == false) System.IO.Directory.CreateDirectory(_FavoriteConfigPath);
                
                if (System.IO.File.Exists(System.IO.Path.Combine(_FavoriteConfigPath, _FavoriteConfigFile)) == true)
                    System.IO.File.Delete(System.IO.Path.Combine(_FavoriteConfigPath, _FavoriteConfigFile));
                FavoritenDocument.Save(System.IO.Path.Combine(_FavoriteConfigPath, _FavoriteConfigFile));
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_UNABLE_TO_SAVE_FAVORITES, ex);
            }
        }

        public void LoadFromDisk()
        {
            try
            {
                _FavoritenParent.Clear();
                _FavoriteDocumentsParent.Clear();

                //load favoriten from disk
                if (System.IO.File.Exists(System.IO.Path.Combine(_FavoriteConfigPath, _FavoriteConfigFile)) == true)
                {
                    System.Xml.XmlDocument FavoritenDocument = new System.Xml.XmlDocument();
                    //Load File
                    FavoritenDocument.Load(System.IO.Path.Combine(_FavoriteConfigPath, _FavoriteConfigFile));
                    System.Xml.XmlNode RootNode =  WMSSoft.Lib.Basic.Xml.cXmlHelpers.GetRootNode(FavoritenDocument);
                    System.Xml.XmlNode ChildsNode = WMSSoft.Lib.Basic.Xml.cXmlHelpers.GetElementNode(RootNode, _FavoritesXMLElement);

                    if (ChildsNode != null && ChildsNode.ChildNodes.Count > 0)
                    {
                        cStartmenuItem FavoriteItem = null;
                        foreach (System.Xml.XmlNode Item in ChildsNode.ChildNodes)
                        {
                            FavoriteItem = null;
                            //Create StartmenuItem - Instance
                            if (System.IO.File.Exists(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText) == true)
                            {
                                string sLinkFileExt = System.IO.Path.GetExtension(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText);
                                if (sLinkFileExt.ToUpper() == ".LNK")
                                {
                                    //Make Instance from Link
                                    FavoriteItem = cStartmenuItem.MakeInstance(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText, _RootFavoritenItem);
                                }
                                else
                                {
                                    //Build Instance normaly
                                    FavoriteItem = new cStartmenuItem(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText,
                                                                      Item.Attributes[_FavoriteXMLElementAttributeName_DisplayName].InnerText, 
                                                                      eLinkExecutionTypes.Program,
                                                                      Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText,
                                                                      eExecutionProcedure.Unknown, eItemType.Link, "",
                                                                      null, _RootFavoritenItem,
                                                                      Item.Attributes[_FavoriteXMLElementAttributeName_Arguments].InnerText, "", "", "");
                                }
                                if (FavoriteItem != null)
                                {
                                    FavoriteItem.ContentType = eContentPanelContentType.Favorites;
                                    _FavoritenParent.AddChild(FavoriteItem);
                                }
                            }
                        }
                    }

                    ChildsNode = WMSSoft.Lib.Basic.Xml.cXmlHelpers.GetElementNode(RootNode, _FavoriteDocumentsXMLElement);

                    if (ChildsNode != null && ChildsNode.ChildNodes.Count > 0)
                    {
                        cStartmenuItem FavoriteItem = null;
                        foreach (System.Xml.XmlNode Item in ChildsNode.ChildNodes)
                        {
                            FavoriteItem = null;
                            //Create StartmenuItem - Instance
                            if (System.IO.File.Exists(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText) == true)
                            {
                                FavoriteItem = cStartmenuItem.MakeInstance(Item.Attributes[_FavoriteXMLElementFileAttributeName].InnerText, _RootFavoritenItem);
                                
                                if (FavoriteItem != null)
                                {
                                    FavoriteItem.ContentType = eContentPanelContentType.Favorites;
                                    _FavoriteDocumentsParent.AddChild(FavoriteItem);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(WMSSoft.Lib.Texte.ErrorMessages.FAVORITE_READER__ERROR_UNABLE_TO_LOAD_FAVORITES, ex);
            }
        }
    }
}
